//
// CGraphController.cpp
// 

/*-----------------------------------------------------*\
			HQ Tech, Make Technology Easy!       
 More information, please go to http://hqtech.nease.net.
/*-----------------------------------------------------*/

#include "stdafx.h"
#include "GlobalDefs.h"
#include "CGraphController.h"
#include "CDXGraph.h"
#include "CDXFilter.h"
#include "CVideoWindow.h"
#include "CLiveCapture.h"

#include "CTVInputFilters.h"
#include "CDVInputFilters.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////
CGraphController::CGraphController()
{
	mGraph       = NULL;
	mVideoWindow = NULL;
	mLiveCapture = NULL;
	
	mInputFilters  = NULL;
	mAudioRenderer = NULL;
	mVideoRenderer = NULL;
	mIsGraphActive = FALSE;
}

CGraphController::~CGraphController()
{
	Deactive();
}

void CGraphController::SetVideoWindow(CVideoWindow * inWindow)
{
	mVideoWindow = inWindow;
}

void CGraphController::SetLiveCapture(CLiveCapture * inData)
{
	mLiveCapture = inData;
}

BOOL CGraphController::IsActiveDeviceLost(IUnknown * pLost)
{
	if (mInputFilters)
	{
		return mInputFilters->IsActiveDeviceLost(pLost);
	}
	return FALSE;
}

BOOL CGraphController::SnapshotToFile(const char * inFile)
{
	return FALSE;
}

BOOL CGraphController::Activate(void)
{
	BOOL pass = CreateGraph();
	if (pass)
	{
		pass = CreateInputFilters();
	}
	if (pass)
	{
		pass = CreateOutputFilters();
	}
	if (pass)
	{
		pass = ConnectFilters();
	}
	if (pass && mVideoWindow)
	{
		mVideoWindow->SetGraph(mGraph);
		PlayGraph();
	}

	// Save the graph status
	mIsGraphActive = pass;
	return pass;
}

void CGraphController::Deactive(void)
{
	StopGraph();
	DisconnectFilters();
	ReleaseInputFilters();
	ReleaseOutputFilters();
	if (mVideoWindow)
	{
		mVideoWindow->SetGraph(NULL);
	}
	DeleteGraph();
	mIsGraphActive = FALSE;
}

BOOL CGraphController::IsPAL(void)
{
	return TRUE;
}

BOOL CGraphController::CreateGraph(void)
{
	mGraph = new CDXGraph();
	if (mGraph->Create())
	{
		mGraph->AddMsgReceiver(this);
		return TRUE;
	}

	DeleteGraph();
	return FALSE;
}

void CGraphController::DeleteGraph(void)
{
	if (mGraph)
	{
		mGraph->RemoveMsgReceiver(this);
		delete mGraph;
		mGraph = NULL;
	}
}

BOOL CGraphController::ConnectFilters(void)
{
	return FALSE;
}

void CGraphController::DisconnectFilters(void)
{
}

BOOL CGraphController::CreateInputFilters(void)
{
	if (mLiveCapture)
	{
		ReleaseInputFilters();

		switch (mLiveCapture->GetDeviceType())
		{
		case DT_DV:
			mInputFilters = new CDVInputFilters(mGraph);
			break;

		case DT_Analog_WDM:
		case DT_Analog_VFW:
		default:
			mInputFilters = new CTVInputFilters(mGraph);
			break;
		}

		mInputFilters->SetLiveCapture(mLiveCapture);
		return mInputFilters->Create();
	}
	return FALSE;
}

void CGraphController::ReleaseInputFilters(void)
{
	SAFE_DELETE(mInputFilters);
}

BOOL CGraphController::CreateOutputFilters(void)
{
	ReleaseOutputFilters();

	BOOL pass = TRUE;
	mVideoRenderer = new CVideoRendererFilter(mGraph->GetGraph());
	mVideoRenderer->SetVMRPreferred(mLiveCapture->IsVMRPreferred());
	pass = mVideoRenderer->CreateFilter();
	mAudioRenderer = new CAudioRendererFilter(mGraph->GetGraph());
	pass = mAudioRenderer->CreateFilter();
	
	return pass;
}

void CGraphController::ReleaseOutputFilters(void)
{
	SAFE_DELETE(mVideoRenderer);
	SAFE_DELETE(mAudioRenderer);
}

BOOL CGraphController::PlayGraph(void)
{
	if (mGraph)
	{
		mGraph->Run();
		return TRUE;
	}
	return FALSE;
}

BOOL CGraphController::PauseGraph(void)
{
	if (mGraph)
	{
		mGraph->Pause();
		return TRUE;
	}
	return FALSE;
}

BOOL CGraphController::StopGraph(void)
{
	if (mGraph)
	{
		mGraph->Stop();
		return TRUE;
	}
	return FALSE;
}

BOOL CGraphController::IsGraphActive(void)
{
	return mIsGraphActive;
}

bool CGraphController::ReceiveMessage(MessageT inMessage, 
									  void * ioParam,
									  void * ioParam2)
{
	switch (inMessage)
	{
	case msg_FilterGraphError:
		StopGraph();
		return true;

	case msg_DShowDeviceLost:
		{
			IUnknown * pDevice = (IUnknown * ) (*((long*)ioParam));
			if (IsActiveDeviceLost(pDevice))
			{
				StopGraph();
			}
		}
		return true;
	}

	return CMsgReceiver::ReceiveMessage(inMessage, ioParam, ioParam2);
}